import axios from "axios";

/**
 * 请求并发控制相关变量
 * requestCount: 当前正在进行的请求数量
 * MAX_CONCURRENT_REQUESTS: 最大并发请求数
 * requestQueue: 存储超出并发限制的请求队列
 */
let requestCount = 0;
const MAX_CONCURRENT_REQUESTS = 5;
const requestQueue = [];

/**
 * 请求缓存相关配置
 * requestCache: 使用Map存储请求缓存
 * CACHE_EXPIRY: 缓存过期时间（毫秒）
 */
const requestCache = new Map();
const CACHE_EXPIRY = 1000 * 60; // 1分钟缓存过期

/**
 * 处理请求队列中的请求
 * 当队列不为空且当前请求数小于最大并发数时，从队列中取出请求并执行
 */
const processQueue = () => {
  if (requestQueue.length === 0 || requestCount >= MAX_CONCURRENT_REQUESTS) return;
  
  const { config, resolve, reject } = requestQueue.shift();
  makeRequest(config).then(resolve).catch(reject);
};

/**
 * 发送实际的HTTP请求
 * @param {Object} config - axios请求配置对象
 * @returns {Promise} 返回请求的Promise对象
 */
const makeRequest = async (config) => {
  requestCount++;
  try {
    const response = await instance.request(config);
    return response;
  } finally {
    requestCount--;
    processQueue(); // 请求完成后处理队列中的下一个请求
  }
};

/**
 * 创建axios实例
 * @param {Object} config
 * @property {string} baseURL - API基础路径
 * @property {number} timeout - 请求超时时间(毫秒)
 * @property {number} retries - 请求失败后的重试次数
 * @property {number} retryDelay - 重试间隔时间(毫秒)
 */
const instance = axios.create({
  baseURL: "/api",
  timeout: 10000,
  retries: 3,
  retryDelay: 1000,
});

/**
 * 请求拦截器
 * 实现以下功能：
 * 1. 请求缓存：检查是否存在未过期的缓存响应
 * 2. 并发控制：限制最大并发请求数，超出限制的请求加入队列
 */
instance.interceptors.request.use(
  async function (config) {
    // 检查是否禁用缓存
    if (config.useCache === false) {
      return config;
    }

    // 生成缓存键，包含请求方法、URL、参数、数据和缓存标识
    const cacheKey = `${config.method}:${config.url}:${JSON.stringify(config.params || {})}:${JSON.stringify(config.data || {})}:${config.cacheKey || ''}`;
    const cachedResponse = requestCache.get(cacheKey);
    
    // 检查是否存在有效的缓存响应
    if (cachedResponse && Date.now() - cachedResponse.timestamp < CACHE_EXPIRY) {
      return Promise.resolve(cachedResponse.data);
    }

    // 并发控制：当前请求数达到上限时，将请求加入队列
    if (requestCount >= MAX_CONCURRENT_REQUESTS) {
      return new Promise((resolve, reject) => {
        requestQueue.push({ config, resolve, reject });
      });
    }

    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

/**
 * 响应拦截器
 * 实现以下功能：
 * 1. 响应缓存：缓存成功的响应数据
 * 2. 错误重试：请求失败时进行重试
 * 3. 错误处理：记录详细的错误信息
 */
instance.interceptors.response.use(
  function (response) {
    // 生成缓存键并存储响应数据
    const config = response.config;
    const cacheKey = `${config.method}:${config.url}:${JSON.stringify(config.params || {})}:${JSON.stringify(config.data || {})}`;
    requestCache.set(cacheKey, {
      data: response,
      timestamp: Date.now(),
    });
    return response;
  },
  async function (error) {
    const config = error.config;
    console.log("请求错误:", config);
    
    // 请求重试机制：在配置的重试次数内进行重试
    config.retryCount = config.retryCount || 0;
    if (config.retryCount < config.retries) {
      config.retryCount++;
      await new Promise(resolve => setTimeout(resolve, config.retryDelay));
      return instance.request(config);
    }

    try {
      // 记录详细的错误信息用于调试
      const errorInfo = {
        url: config?.url,
        method: config?.method,
        params: config?.params,
        data: config?.data,
        status: error.response?.status,
        statusText: error.response?.statusText,
        stack: error.stack,
      };
      console.error("请求错误:", errorInfo);
      return Promise.reject(error);
    } catch (err) {
      console.error("拦截器捕获错误:", err);
      return Promise.reject(error);
    }
  }
);

export default instance;
